home *** CD-ROM | disk | FTP | other *** search
- /* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Simple Timer.
- *
- * The Initial Developer of the Original Code is
- * George Bradt.
-
- * Portions created by the Initial Developer are Copyright (C) 2009
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
- var SimpleTimerCountdown = {
- // For reference, not used
- countdownTimer: {timeDisplay: "",
- recurring: false,
- description: "",
- timeMilli: 0,
- timeFinishedMilli: 0,
- paused: false
- },
- countdownSep: "\x1D", // used to separate countdowns in pref.
-
- // Called when loading Countdown time entry dialog.
-
- onLoadCountdown: function() {
- var strbundle = document.getElementById("simtim-strings");
- var prefs = Components.classes["@mozilla.org/preferences-service;1"].
- getService(Components.interfaces.nsIPrefService).
- getBranch("extensions.simpletimer@grbradt.org.");
- var Application = Components.classes["@mozilla.org/fuel/application;1"].
- getService(Components.interfaces.fuelIApplication);
- var countdownTable = [];
-
- document.getElementById("simtim-tboxCountdownHours").value =
- prefs.getIntPref("countdownHours");
- document.getElementById("simtim-tboxCountdownMinutes").value =
- prefs.getIntPref("countdownMinutes");
- document.getElementById("simtim-tboxCountdownSeconds").value =
- prefs.getIntPref("countdownSeconds");
-
- if ( Application.storage.has("countdownTable") ) {
- countdownTable = Application.storage.get("countdownTable", "ERR");
-
- if ( countdownTable === "ERR" ) {
- alert(strbundle.getString("alert.error.loading.countdowns"));
- return;
- }
- }
- else {
- alert(strbundle.getString("alert.error.loading.countdowns"));
- return;
- }
-
- var treeChildren = document.getElementById("simtim-treeItems");
-
- // Clear the old tree data.
- this.onDeleteAllCountdown();
-
- for ( var i in countdownTable ) {
- this.addTreeRow(treeChildren, countdownTable[i]);
- }
- },
-
- // Called when Add/OK button is clicked.
-
- onAddOkCountdown: function() {
- if ( this.onAddCountdown() ) {
- this.onOKCountdown();
- window.close();
- }
- },
-
- // Called when Add button is clicked.
-
- onAddCountdown: function() {
- var strbundle = document.getElementById("simtim-strings");
- var hours = document.getElementById("simtim-tboxCountdownHours").value;
- var minutes = document.getElementById("simtim-tboxCountdownMinutes").value;
- var seconds = document.getElementById("simtim-tboxCountdownSeconds").value;
-
- if ( hours === "0" &&
- minutes === "0" &&
- seconds === "0" ) {
- alert(strbundle.getString("alert.warning.nonzero.user"));
- return false;
- }
-
- var timeDisplay = this.padTime(hours) + ":" + this.padTime(minutes) + ":" + this.padTime(seconds);
- var timeMilli = this.convertTimeToMilli(hours, minutes, seconds);
- var descr = document.getElementById("simtim-tboxCountdownDescr").value;
- var recurring = document.getElementById("simtim-cboxCountdownRecurring").checked;
- var tree = document.getElementById("simtim-treeCountdown");
- var boxobject = tree.boxObject;
- boxobject.QueryInterface(Components.interfaces.nsITreeBoxObject);
- var treeChildren = document.getElementById("simtim-treeItems");
- var treeItems = treeChildren.hasChildNodes() ? treeChildren.childNodes: null;
-
- var data = {timeDisplay: timeDisplay, recurring: recurring, description: descr,
- timeMilli: timeMilli, timeFinishedMilli: 0, paused: false};
-
- this.addTreeRow(treeChildren, data);
-
- // Select the added row.
- var rowIndex = treeItems ? treeItems.length - 1 : 0;
- tree.view.selection.select(rowIndex);
-
- // Ensure the added/updated row is visible, tree displays 5 rows (unless dlg stretched).
- if ( treeItems && treeItems.length > 5 ) {
- boxobject.ensureRowIsVisible(rowIndex);
- }
-
- // Clear the description textbox.
- document.getElementById("simtim-tboxCountdownDescr").value = "";
-
- return true;
- },
-
- // Add a timer to the tree.
-
- addTreeRow: function(treeChildren, data) {
- var item = document.createElement("treeitem");
- var row = document.createElement("treerow");
- var cell;
-
- // First cell is "timeDisplay", not editable.
- cell = document.createElement("treecell");
- cell.setAttribute("label", data.timeDisplay);
- cell.setAttribute("value", data.timeMilli);
- cell.setAttribute("timeFinishedMilli", data.timeFinishedMilli);
- cell.setAttribute("editable", "false");
- row.appendChild(cell);
-
- // Second cell is "recurring", displayed as a checkbox.
- cell = document.createElement("treecell");
- cell.setAttribute("value", data.recurring);
- row.appendChild(cell);
-
- // Third cell is "descr", the optional description. Stash paused.
- cell = document.createElement("treecell");
- cell.setAttribute("label", data.description);
- cell.setAttribute("value", data.paused);
- row.appendChild(cell);
-
- // Add the treerow onto treeitem, append item.
- item.appendChild(row);
- treeChildren.appendChild(item);
- },
-
- // Called when Delete button is clicked.
-
- onDeleteCountdown: function() {
- var strbundle = document.getElementById("simtim-strings");
- var tree = document.getElementById("simtim-treeCountdown");
-
- if ( tree.currentIndex < 0 ) {
- // User didn't make a selection.
- alert(strbundle.getString("alert.warning.no.item.selected"));
- }
- else {
- var start = {};
- var end = {};
- var treeItem;
- var numRanges = tree.view.selection.getRangeCount();
-
- // Start with the last selection range and work up.
- for ( var i = numRanges - 1; i >= 0; i-- ) {
- tree.view.selection.getRangeAt(i,start,end);
-
- // Within a range, delete from the bottom up.
- for ( var j = end.value; j >= start.value; j-- ) {
- treeItem = tree.view.getItemAtIndex(j);
- treeItem.parentNode.removeChild(treeItem);
- }
- }
- }
- },
-
- // Called when Del All button is clicked.
-
- onDeleteAllCountdown: function() {
- var treeChildren = document.getElementById("simtim-treeItems");
-
- // Remove from the bottom.
- while ( treeChildren.hasChildNodes() ) {
- treeChildren.removeChild(treeChildren.lastChild);
- }
- },
-
- // Save the favourite timers list in a pref.
- // Called when Save List button is clicked.
-
- onSaveList: function() {
- var strbundle = document.getElementById("simtim-strings");
- var str = Components.classes["@mozilla.org/supports-string;1"].
- createInstance(Components.interfaces.nsISupportsString);
-
- // Objects stored as JSON strings in the pref.
- var json = Components.classes["@mozilla.org/dom/json;1"].
- createInstance(Components.interfaces.nsIJSON);
-
- var treeChildren = document.getElementById("simtim-treeItems");
-
- if ( treeChildren.hasChildNodes() ) {
- // Get confirmation.
- var button = confirm(strbundle.getString("confirm.save.timer.list"));
-
- if ( !button ) {
- // User didn't click OK.
- return;
- }
-
- // Build pref string of all timers from dialog Countdown timers tree.
- var row, timeDisplay, recurring, description, paused,
- timeMilli, timeFinishedMilli, timeNode;
- var prefString = "";
- var currTimeMilli = new Date().getTime();
-
- var treeItems = treeChildren.childNodes;
- var len = treeItems.length;
-
- for ( var i = 0; i < len; i++ ) {
- row = treeItems[i].firstChild;
- timeNode = row.firstChild;
- timeDisplay = timeNode.getAttribute("label");
- timeMilli = parseInt(timeNode.getAttribute("value"), 10);
-
- // Convert string attribute to boolean.
- recurring = ( row.firstChild.nextSibling.getAttribute("value") === "true" ) ?
- true : false;
-
- description = row.lastChild.getAttribute("label");
-
- try {
- prefString += json.encode( {timeDisplay: timeDisplay, recurring: recurring,
- description: description, timeMilli: timeMilli, timeFinishedMilli: 0,
- paused: false} ) + this.countdownSep;
- }
- catch(e) {
- alert(strbundle.getString("alert.error.encoding.timer"));
- return;
- }
- }
-
- // Remove last separator.
- if ( prefString ) {
- prefString = prefString.substring(0, prefString.length - 1);
- }
-
- str.data = prefString;
- window.opener.SimpleTimer.prefs.setComplexValue("favCountdowns",
- Components.interfaces.nsISupportsString, str);
- }
- else {
- alert(strbundle.getString("msg.no.timers"));
- }
- },
-
- // Load the favourite timers list from pref.
- // Called when Load List button is clicked.
-
- onLoadList: function() {
- var strbundle = document.getElementById("simtim-strings");
-
- if ( !window.opener.SimpleTimer.favCountdowns ) {
- alert(strbundle.getString("msg.timers.no.list"));
- return;
- }
-
- // Objects stored as JSON strings in the pref.
- var json = Components.classes["@mozilla.org/dom/json;1"].
- createInstance(Components.interfaces.nsIJSON);
-
- var favCountdownArray = window.opener.SimpleTimer.favCountdowns.split(this.countdownSep);
- var treeChildren = document.getElementById("simtim-treeItems");
- var tempArray = [];
-
- for ( var i in favCountdownArray ) {
- try {
- tempArray[i] = json.decode(favCountdownArray[i]);
- }
- catch(e) {
- alert(strbundle.getString("alert.error.decoding.timer"));
- return;
- }
-
- this.addTreeRow(treeChildren, tempArray[i]);
- }
- },
-
- // Pad a display time with zero if necessary.
-
- padTime: function(time) {
- return ( ( time < 10 ) ? "0" + time : time );
- },
-
- // Convert a time to milliseconds.
-
- convertTimeToMilli: function(hrs, mins, secs) {
- return ( ( hrs * 60 * 60 * 1000 ) + ( mins * 60 * 1000 ) + ( secs * 1000 ) );
- },
-
- // Called when user clicks OK.
-
- onOKCountdown: function() {
- window.opener.SimpleTimer.prefs.setIntPref("countdownHours",
- document.getElementById("simtim-tboxCountdownHours").value);
- window.opener.SimpleTimer.prefs.setIntPref("countdownMinutes",
- document.getElementById("simtim-tboxCountdownMinutes").value);
- window.opener.SimpleTimer.prefs.setIntPref("countdownSeconds",
- document.getElementById("simtim-tboxCountdownSeconds").value);
-
- this.buildCountdownTable();
-
- var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService();
- var wmed = wm.QueryInterface(Components.interfaces.nsIWindowMediator);
- var enumerator = wmed.getEnumerator("navigator:browser");
-
- while ( enumerator.hasMoreElements() ) {
- var win = enumerator.getNext();
-
- win.SimpleTimer.cancelTimerInProgress();
-
- if ( win.SimpleTimer.getCountdownTable() ) {
- win.SimpleTimer.setCountdownTimer();
- }
- }
- },
-
- // Construct an array of countdown timer objects.
- // Called when the user clicks OK or Add/OK.
-
- buildCountdownTable: function() {
- var Application = Components.classes["@mozilla.org/fuel/application;1"].
- getService(Components.interfaces.fuelIApplication);
-
- var treeChildren = document.getElementById("simtim-treeItems");
- var countdownTable = [];
-
- if ( treeChildren.hasChildNodes() ) {
- // Build table of all timers from dialog Countdown timers tree.
- var row, timeDisplay, recurring, description, paused,
- timeMilli, timeFinishedMilli, timeNode;
- var currTimeMilli = new Date().getTime();
-
- var treeItems = treeChildren.childNodes;
- var len = treeItems.length;
-
- for ( var i = 0; i < len; i++ ) {
- row = treeItems[i].firstChild;
- timeNode = row.firstChild;
- timeDisplay = timeNode.getAttribute("label");
- timeMilli = parseInt(timeNode.getAttribute("value"), 10);
- timeFinishedMilli = parseInt(timeNode.getAttribute("timeFinishedMilli"), 10);
-
- // Convert string attribute to boolean.
- recurring = ( row.firstChild.nextSibling.getAttribute("value") === "true" ) ?
- true : false;
-
- // Check if an existing timer expired while dialog open.
- if ( timeFinishedMilli > 0 && currTimeMilli > timeFinishedMilli ) {
- if ( recurring ) {
- // Cannot use timeMilli, since it changes if paused.
- var timeDisplayMilli = SimpleTimer.convertClockToMilli(timeDisplay);
-
- timeFinishedMilli += timeDisplayMilli *
- Math.ceil((currTimeMilli - timeFinishedMilli) / timeDisplayMilli);
- }
- else {
- continue;
- }
- }
-
- description = row.lastChild.getAttribute("label");
- paused = ( row.lastChild.getAttribute("value") === "true" ) ?
- true : false;
-
- // Don't use i for index, as some tree items may be bypassed.
- countdownTable[countdownTable.length] = {timeDisplay: timeDisplay,
- recurring: recurring,
- description: description,
- timeMilli: timeMilli,
- timeFinishedMilli: timeFinishedMilli,
- paused: paused
- };
- }
- }
-
- Application.storage.set("countdownTable", countdownTable);
- },
-
- // Construct an array of countdown objects from the countdowns pref,
- // and store via FUEL. Called at startup.
-
- buildCountdownTableFromPref: function(countdowns) {
- var strbundle = document.getElementById("simtim-strings");
- var currTimeMilli = new Date().getTime();
-
- // Objects stored as JSON strings in the pref.
- var json = Components.classes["@mozilla.org/dom/json;1"].
- createInstance(Components.interfaces.nsIJSON);
-
- var eventDescription, eventRecurring;
- var tempArray = [];
- var expiredArray = [];
- var countdownTable = [];
- var countdownArray = countdowns.split(this.countdownSep);
-
- for ( var i in countdownArray ) {
- tempArray[i] = json.decode(countdownArray[i]);
-
- if ( !tempArray[i].hasOwnProperty('paused') ) {
- tempArray[i].paused = false;
- }
-
- // Exclude timers that expired while browser closed. Always include recurring,
- // adjusting its finish time if necessary.
- if ( tempArray[i].recurring && currTimeMilli >= tempArray[i].timeFinishedMilli ) {
- tempArray[i].timeFinishedMilli +=
- tempArray[i].timeMilli *
- Math.ceil((currTimeMilli - tempArray[i].timeFinishedMilli) / tempArray[i].timeMilli);
- }
-
- // Paused timer will get a valid finish time only when resumed.
- // This will sort to the top.
- if ( tempArray[i].paused ) {
- tempArray[i].timeFinishedMilli = 0;
- }
-
- if ( currTimeMilli <= tempArray[i].timeFinishedMilli ||
- tempArray[i].paused ) {
- countdownTable[countdownTable.length] = tempArray[i];
- }
- else {
- // Expired, save for display in slider alert.
- expiredArray.push({timeDisplay: tempArray[i].timeDisplay,
- description: tempArray[i].description});
-
- if ( SimpleTimer.eventLogging ) {
- eventDescription = ( tempArray[i].description ) ?
- tempArray[i].description :
- strbundle.getString("msg.none");
-
- eventRecurring = ( tempArray[i].recurring ) ?
- strbundle.getString("msg.yes") :
- strbundle.getString("msg.no");
-
- // Pass event type, event time, recurring, status, description, URL(N/A).
- SimpleTimerEventLog.logEvent(strbundle.getString("msg.countdown"),
- tempArray[i].timeDisplay,
- eventRecurring,
- strbundle.getString("msg.expired"),
- eventDescription,
- strbundle.getString("msg.not.applicable"));
- }
- }
- }
-
- // If opening another browser window, user would have seen the expired alerts.
- if ( !SimpleTimer.otherBrowserWindowOpen() ) {
- if ( countdownTable.length === 0 ) {
- var params = { displayItems: expiredArray, msg: strbundle.getString("msg.countdown.timers.none" )};
- setTimeout(SimpleTimerSliderAlert.addMessageToQueue, 5000, params);
- setTimeout("SimpleTimer.playSound(3)", 5000);
- }
- else if (countdownTable.length !== countdownArray.length ) {
- params = { displayItems: expiredArray, msg: strbundle.getString("msg.countdown.timers.some" )};
- setTimeout(SimpleTimerSliderAlert.addMessageToQueue, 5000, params);
- setTimeout("SimpleTimer.playSound(3)", 5000);
- }
- else {
- params = { displayItems: null, msg: strbundle.getString("msg.countdown.timers.all" )};
- setTimeout(SimpleTimerSliderAlert.addMessageToQueue, 5000, params);
- setTimeout("SimpleTimer.playSound(3)", 5000);
- }
- }
-
- Application.storage.set("countdownTable", countdownTable);
-
- if ( countdownTable.length !== countdownArray.length ) {
- // Update pref in case another window opened.
- this.updateCountdownPref();
- }
- },
-
- // Write countdowns pref from countdown table. Called from SimpleTimer.
-
- updateCountdownPref: function() {
- var prefs = Components.classes["@mozilla.org/preferences-service;1"].
- getService(Components.interfaces.nsIPrefService).
- getBranch("extensions.simpletimer@grbradt.org.");
-
- // For Unicode.
- var str = Components.classes["@mozilla.org/supports-string;1"].
- createInstance(Components.interfaces.nsISupportsString);
-
- var Application = Components.classes["@mozilla.org/fuel/application;1"].
- getService(Components.interfaces.fuelIApplication);
-
- var countdownTable = [];
-
- if ( Application.storage.has("countdownTable") ) {
- countdownTable = Application.storage.get("countdownTable", "ERR");
-
- if ( countdownTable === "ERR" ) {
- alert(strbundle.getString("alert.error.loading.countdowns"));
- return;
- }
- }
- else {
- alert(strbundle.getString("alert.error.loading.countdowns"));
- return;
- }
-
- // Objects stored as JSON strings in the pref.
- var json = Components.classes["@mozilla.org/dom/json;1"].
- createInstance(Components.interfaces.nsIJSON);
-
- var prefString = "";
-
- for ( var i in countdownTable ) {
- prefString += json.encode(countdownTable[i]) + this.countdownSep;
- }
-
- // Remove last separator.
- if ( prefString ) {
- prefString = prefString.substring(0, prefString.length - 1);
- }
-
- str.data = prefString;
- SimpleTimer.prefs.setComplexValue("countdowns",
- Components.interfaces.nsISupportsString, str);
- },
-
- // Sort the countdown table on objects timeFinishedMilli property.
- // Called from SimpleTimer.setCountdownTimer().
-
- sortCountdownTable: function(a, b) {
- var x = a.timeFinishedMilli;
- var y = b.timeFinishedMilli;
-
- return ( (x < y) ? -1 : ( (x > y) ? 1 : 0 ) );
- },
-
- // Dump to console.
-
- dumpCountdownObject: function (countdownTimer) {
- this.debug("\nCountdown timer data:");
- this.debug("Countdown Time for Display: " + countdownTimer.timeDisplay);
- this.debug("Recurring?: " + countdownTimer.recurring);
- this.debug("Description: " + countdownTimer.description);
- this.debug("Countdown time (millisecs): " + countdownTimer.timeMilli);
- this.debug("Countdown finish time (millisecs): " + countdownTimer.timeFinishedMilli);
- },
-
- // Debug messages to console.
-
- debug: function (aMsg) {
- setTimeout(function() { throw new Error("[debug] " + aMsg); }, 0);
- }
- };